regexjava模式。带重叠分隔符的split()
首先,我知道有人问过类似的问题,比如:
How to split a string, but also keep the delimiters?
但是,我在使用模式实现字符串拆分时遇到了问题。split(),其中模式基于分隔符列表,但有时它们会重叠。以下是一个例子:
目标是基于一组由斜杠包围的已知码字分割字符串,其中我需要保留分隔符(码字)本身及其后面的值(可能是空字符串)
对于本例,码字为:
/ABC/
/DEF/
/GHI/
基于上面引用的线程,使用“向前看”和“向后看”将字符串标记为码字和值,按照如下方式构建模式:
((?<=/ABC/)|(?=/ABC/))|((?<=/DEF/)|(?=/DEF/))|((?<=/GHI/)|(?=/GHI/))
工作字符串:
"123/ABC//DEF/456/GHI/789"
使用split,这将很好地标记为:
"123","/ABC/","/DEF/","456","/GHI/","789"
问题字符串(注意“ABC”和“DEF”之间的单斜杠):
"123/ABC/DEF/456/GHI/789"
这里的期望值是“DEF/456”是“/ABC/”码字之后的值,因为“DEF/”位实际上不是一个码字,只是碰巧看起来像一个
预期结果是:
"123","/ABC/","DEF/456","/GHI/","789"
实际结果是:
"123","/ABC","/","DEF/","456","/GHI/","789"
正如您所看到的,“ABC”和“DEF”之间的斜杠作为标记本身被隔离
我尝试了其他线程的解决方案,只使用“向前看”或“向后看”,但它们似乎都有相同的问题。感谢您的帮助
# 1 楼答案
如果您可以使用
find
而不是split
,使用一些非贪婪匹配,请尝试以下方法:输出:
# 2 楼答案
使用积极和消极环视的组合:
通过在单个“向前看/向后看”中使用交替,也有相当大的简化
见live demo
# 3 楼答案
以下是一些TDD principles(红绿重构),我将如何实现这种行为:
书写规格(红色)
我定义了一组单元测试来解释我是如何理解您的“标记化过程”的。如果任何测试不符合您的期望,请随时告诉我,我将相应地编辑我的答案
根据规范实施(绿色)
这门课使以上所有的测试都通过了
改进实现(重构)
目前还没有完成(没有足够的时间,我现在可以花在这个答案上)。如果您要求,我将很乐意对
Tokenizer
进行重构(但稍后会进行)。:-)或者你也可以自己做,因为你有单元测试来避免回归